# Outer Ring - A 2d space combat and trading game
# Copyright (C) 2009 Steve McGrath
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

import os
import sys
from math import *

import pygame
from pygame.locals import *

import gameEngine
from util import *
from resource import *
import pyconsole
from console import *


class FPSlabel(gameEngine.Label):
    def __init__(self):
        gameEngine.Label.__init__(self)
        self.bgColor = ((0x00, 0x00, 0x00))
        self.fgColor = ((0xFF, 0xFF, 0xFF))
    
    def update(self):
        self.text = str(round((game.clock.get_fps()), 1))
        gameEngine.Label.update(self)
        

class Ship(gameEngine.SuperSprite):
    def __init__(self, scene, name):
        """
        Returns a new ship instance with attributes loaded from an XML file
        name: the resource name to open
        """
        gameEngine.SuperSprite.__init__(self, scene)
        self.attrs = getresource(name)
        self.setImage(os.path.join("sprites", self.attrs['spritefile']), None)
        self.setSpeed(0)
        self.setAngle(0)
        
        self.thrust = float(self.attrs['thrust'])
        self.turnrate = int(self.attrs['turnrate'])
        self.maxSpeed = int(self.attrs['maxspeed'])
        self.hull = int(self.attrs['hull'])
        self.weapons = []
        self.weapons.append(Weapon(scene, 'bob', self))
        
    def hit(self):
        self.hull -= 3
        print self.hull
        if self.hull <= 0:
            self.kill()
            


class EnemyShip(Ship):
    """The class is a Ship with the beginnings of AI"""
    
    def __init__(self, scene, name):
        Ship.__init__(self, scene, name)
        self.target = self.scene.ship
        
    def checkEvents(self):
        bearing = self.dirTo((self.target.x, self.target.y)) - self.rotation
        if bearing < 0:
            self.rotateBy(-self.turnrate)
        if bearing > 1:
            self.rotateBy(self.turnrate)
        print bearing
        for wep in self.weapons:
            wep.fire()
        pass
    


class OwnShip(Ship):
    """This class extends Ship with extra methods needed for
    the player's ship"""
    
    def __init__(self, scene, name):
        Ship.__init__(self, scene, name)
    
    def checkEvents(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.rotateBy(self.turnrate)
        if keys[pygame.K_RIGHT]:
            self.rotateBy(-self.turnrate)
        if keys[pygame.K_UP]:
            self.addForce(self.thrust, self.rotation)
        if keys[pygame.K_SPACE]:
            for wep in self.weapons:
                wep.fire()
                
    def hit(self):
        if game.console.getvar('god') == 0:
            Ship.hit(self)

class Weapon(): # I hate this class. Really.
    def __init__(self, scene, name, ship):
        self.scene = scene
        self.ship = ship
        self.attrs = getresource(name)
        self.delay = int(self.attrs['cycletime'])
        self.cycletime = self.delay
        self.p_attrs = getresource(self.attrs['projectile'])

    
    def fire(self):
        if self.delay == 0:
            self.projectile = Projectile(self.scene, self.ship, self.p_attrs)
            self.delay = self.cycletime
        self.delay -= 1
        

class Projectile(gameEngine.SuperSprite): # I hate this class more.
    def __init__(self, scene, ship, attrs):
        gameEngine.SuperSprite.__init__(self, scene)
        self.ship = ship
        self.setImage(os.path.join('sprites', attrs['spritefile']), None)
        self.setBoundAction(self.HIDE)
        self.lifetime = int(attrs['lifetime'])
        self.speed = int(attrs['speed'])
        
        # the following math is used to calculate projectile launch speed,
        # which it does. It also offsets the projectile's origin away from
        # the center of the ship. This, it does not do so well.
        self.setPosition((ship.x, ship.y))
        #self.setPosition(((self.scene.ship.x + (-30*cos(radians(self.rotation)))),
         #               self.scene.ship.y + (30*sin(radians(self.rotation)))))
        self.setDX(self.speed * (-cos(ship.rotation)) + ship.dx)
        self.setDY(self.speed * (sin(ship.rotation)) + ship.dy)
        self.speed += ship.speed
        self.setAngle(ship.rotation)
        self.update()
        self.add(self.scene.mainSprites)

    def checkEvents(self):
        collision = self.collidesGroup(self.scene.mainSprites)
        if collision != self.ship:
            if isinstance(collision, Ship):
                print "hit:", collision
                collision.hit()
                self.kill()
                del(self)
                return
        self.lifetime -= 1
        if self.lifetime == 0:
            self.kill()
            del(self)


class Game(gameEngine.Scene):
    def __init__(self, xres, yres):
        gameEngine.Scene.__init__(self, xres, yres)
        self.console = pyconsole.Console(self.screen, (0,0,600,150))
        self.console.setvar('god', 0)
        self.consolestate = 0 # 0: Inactive. 1:Active. 2: Going inactive
        self.ship = OwnShip(self, 'ted')
        self.enemyship = EnemyShip(self, 'shadow')
        self.enemyship.setPosition(((xres / 2), (yres / 2)))
        self.sprites = [self.ship, self.enemyship]
        self.setCaption("Outer Ring 0.0.0")
        # self.fpslabel = FPSlabel()
        # self.sprites.append(self.fpslabel)
    def doEvents(self, event):
        self.console.process_input()        
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                self.stop()
            if event.key == pygame.K_BACKQUOTE:
                self.console.set_active()
                self.consolestate = 1

    def update(self):
        # print game.clock.get_fps()
        pass

    def postDraw(self):
        self.console.draw()
        crect = self.console.rect.inflate(1,1) # The rect obtained from the console doesn't include the border.
        if not self.console.active:
            if self.consolestate == 1:
                self.consolestate = 2
            if self.consolestate == 2:
                self.screen.blit(self.background, crect, crect)
                self.dirty.append(crect)
                self.consolestate = 0
                return
        if self.consolestate != 0:
            self.dirty.append(crect)

if __name__ == '__main__':
    xres, yres = 800, 600
    game = Game(xres, yres)
    game.start()
    
    